
using System.Collections.Generic;
using FairyGUI;
using UnityEngine;
using SimpleJson;
using System;

namespace ABA
{
    public enum EModuleDir
    {
        none,
        left,
        right,
        up,
        down
    }

    public class ModuleParam
    {
        public int type;
        public JsonObject objParam;
        public string from;

        public ModuleParam()
        {
            from = "";
            objParam = null;
        }
    }

    public class ModuleConf
    {
        // public int type;
        public Action<ModuleParam, Action, EModuleDir> enter;
        public Action<ModuleParam, Action, EModuleDir> exit;
    }

    // 所有全屏类（VIEW）的UI,必须用Module管理，方便回退等操作
    // 各个模块间跳转的总入口及出口，一般全屏的功能及VIEW类型的都得用这个管理及
    // 如果是有多个进入战斗界面的入口，要有一个管理进入及退出战斗的类，方便退出的时候能退出到入口位置，可以不仅是战斗，其他的全屏模块也行
    // 如果是只有一个入口的模块，可以不用此接口管理
    public class ModuleBase : Singleton<ModuleBase>
    {
        protected Dictionary<int, ModuleConf> moduleList;

        public void InitModuleList(Dictionary<int, ModuleConf> list)
        {
            moduleList = list;
        }
        
        ModuleParam _cur;
        Stack<ModuleParam> _param = new Stack<ModuleParam>();

        JsonObject _objParam;
        string _from;
        public void Push(int type, JsonObject objParam = null, string from = "")
        {
            // _objParam = objParam;
            // _from = from;
            // __Push(type);
            PushAct(type, EModuleDir.none, objParam, from);
        }
        public void PushAndPop(int type, int skip = 1, EModuleDir direction = EModuleDir.left, JsonObject objParam = null, string from = "")
        {
            PushAct(type, direction, objParam, from);

            for (int i = 0; i < skip; ++i)
            {
                var p = _param.Pop();
                _cur = p;
            }
        }
        public void PushAct(int type, EModuleDir direction = EModuleDir.left, JsonObject objParam = null, string from = "")
        {
            _objParam = objParam;
            _from = from;
            __Push(type, direction);
        }
        // 隐藏当前view，显示下一个view
        private void __Push(int type, EModuleDir direction = EModuleDir.none)
        {
            FGUIManager.inst.HideAllDialog();

            // 防止太多了
            if (_param.Count >= 200)
            {
                var yy = new Stack<ModuleParam>();
                var xx = _param.ToArray();
                for (int i = xx.Length - 100; i < xx.Length; i++)
                {
                    yy.Push(xx[i]);
                }
                _param = yy;
            }

            if (_cur != null)
            {
                if (direction != EModuleDir.none)
                {
                    var old = _cur;
                    ExitModule(old, () =>
                    {
                    }, direction);
                    _param.Push(_cur);
                    _cur = new ModuleParam();
                    _cur.type = type;
                    _cur.objParam = _objParam;
                    _cur.from = _from;
                    EnterModule(_cur, () =>
                    {
                    }, direction);
                }
                else
                {
                    ExitModule(_cur, () =>
                    {
                        _param.Push(_cur);
                        _cur = new ModuleParam();
                        _cur.type = type;
                        _cur.objParam = _objParam;
                        _cur.from = _from;

                        EnterModule(_cur, () =>
                        {
                        });
                    });
                }
            }
            else
            {
                _cur = new ModuleParam();
                _cur.type = type;
                _cur.objParam = _objParam;
                _cur.from = _from;
                EnterModule(_cur, () =>
                {
                });
            }
        }

        public void Pop()
        {
            FGUIManager.inst.HideAllDialog();

            var p = _param.Pop();
            ExitModule(_cur, () =>
            {
                EnterModule(p, () =>
                {
                });
                _cur = p;
            });
        }

        private void ExitModule(ModuleParam cur, Action cb, EModuleDir actDirection = EModuleDir.none)
        {
            if(moduleList.ContainsKey(cur.type))
            {
                moduleList[cur.type].exit?.Invoke(cur,cb,actDirection);
            }
        }

        private void EnterModule(ModuleParam cur, Action cb, EModuleDir actDirection = EModuleDir.none)
        {
            if(moduleList.ContainsKey(cur.type))
            {
                moduleList[cur.type].enter?.Invoke(cur,cb,actDirection);
            }
        }
    }
}



